package com.dmxh.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.dmxh.dto.UserDto;
import com.dmxh.mapper.TbUserMapper;
import com.dmxh.pojo.TbUser;
import com.dmxh.pojo.TbUserExample;
import com.dmxh.service.UserService;
import com.dmxh.util.ShiroUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wxy
 * @since 2024-05-20
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private TbUserMapper userMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JavaMailSender javaMailSender;

    @Override
    public String generateCode(String phone) {
        String code = "";
        if (StrUtil.isNotEmpty(phone)) {/*判断手机号不空*/
            //查询当前手机号是否已经注册  如果已经注册就提示用户去登录
            TbUserExample example = new TbUserExample();
            example.createCriteria().andPhoneEqualTo(phone);
            List<TbUser> tbUsers = userMapper.selectByExample(example);
            if (ObjectUtil.isNotEmpty(tbUsers)) {//用户存在
                return "当前用户已存在,请直接去登录";
            } else {//用户不存在
                if (stringRedisTemplate.opsForValue().get(phone) == null) {//判断redis中有没有未过期的验证码
                    rocketMQTemplate.convertAndSend("generateCode", phone);/*过期重新发送验证码*/
                } else {
                    code = stringRedisTemplate.opsForValue().get(phone);//旧的验证码  没过期直接将原先的验证码发给用户
                }
            }
        } else {
            return "手机号为空";
        }
        return code;
    }

    @Override
    public String registerUser(UserDto userDto) {
        String tablephone = null;
        String oldCode = stringRedisTemplate.opsForValue().get(userDto.getPhone());
        //验证码失效  清重新获取
        if (ObjectUtil.isEmpty(oldCode)) {//有
            rocketMQTemplate.convertAndSend("generateCode", userDto.getPhone());
            return "验证码已经获取成功,去验证吧";
        }
        if (!userDto.getCode().equals(oldCode)) {//判断用户验证码一致
            return "验证码不一致 请重新输入";
        }
        TbUserExample example = new TbUserExample();
        example.createCriteria().andPhoneEqualTo(userDto.getPhone());
        List<TbUser> tbUsers = userMapper.selectByExample(example);//查询是否注册过相同的号码
        for (TbUser tbUser : tbUsers) {
            tablephone = tbUser.getPhone();
        }
//        if (!userDto.getPhone().equals(tablephone)) {
//            return "用户已经存在  请去登录吧";
//        }
        if (Objects.equals(userDto.getPhone(), tablephone)) {
            return "用户已经存在 先去登录吧";
        }
        String salt1 = ShiroUtils.generateSalt(5);
        String md5 = ShiroUtils.encryptPassword("md5", userDto.getPassword(), salt1, 5);/*加密次数 和 解密次数成正比*/
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(userDto, tbUser);
        tbUser.setPassword(md5);//加密
        tbUser.setSalt(salt1);//加盐
        tbUser.setEmail("3287618159@qq.com");
        tbUser.setCreated(new Date());
        tbUser.setUpdated(new Date());
        return (userMapper.insertSelective(tbUser) == 1) ? "增加成功" : "增加失败";
    }

    @Override
    public Map<String, Object> getUserAll() {
        List<TbUser> tbUsers = this.userMapper.selectByExample(null);
        HashMap<String, Object> map = new HashMap<>();
        map.put("userlist", tbUsers);
        return map;
    }


    /*-------------------------------------------------login-----------------------------------------------------*/

    @Override
    public TbUser queryUserByUsername(String username) {
        TbUserExample example = new TbUserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<TbUser> tbUsers = userMapper.selectByExample(example);
        if (tbUsers.size() > 0) {
            return tbUsers.get(0);/*如果有数据就直接获取第一个字段*/
        }
        return null;/*否则获取不到*/
    }

    @Override
    public TbUser getUserByName(String principal) {
        TbUserExample example = new TbUserExample();
        example.createCriteria().andUsernameEqualTo(principal);
        List<TbUser> tbUsers = userMapper.selectByExample(example);
        return (ObjectUtil.isNotEmpty(tbUsers)) ? tbUsers.get(0) : null;
    }

    @Override
    public Object queryUserByPhoneAndUpdate(String userName) {
        TbUser user = userMapper.queryByUserName(userName);
        TbUser tbUser = new TbUser();
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户名称为空");
        }
        String randomPwd = RandomUtil.randomNumbers(4);
        String salt = ShiroUtils.generateSalt(6);
        String md5 = ShiroUtils.encryptPassword("md5", randomPwd, salt, 5);
        Long id = user.getId();
        String eamil = null;
        if (Objects.nonNull(user.getEmail())) {
            eamil = user.getEmail();
        }
        tbUser.setId(id);
        tbUser.setPassword(md5);
        tbUser.setSalt(salt);
        int i = userMapper.updateByPrimaryKeySelective(tbUser);
        if (i > 0) {
            /*修改成功，发送邮件通知用户登录*/
//          创建发送邮件对象
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//          发件人邮箱
            simpleMailMessage.setFrom(eamil);
//          定义一个数组 将发件人和收件人放进去
            String[] str = {eamil};/*从数据库查询到的email根据获取到的email进行发送邮件*/
            simpleMailMessage.setTo(str);
//          设置邮件主题目
            simpleMailMessage.setSubject("重置密码");//标题
            simpleMailMessage.setText("重置成功(O'v'O),请使用当前密码登录:" + randomPwd);//内容  这里是hutool生成的随机密码
//          设置发送时间
            simpleMailMessage.setSentDate(new Date());
//          执行发送
            javaMailSender.send(simpleMailMessage);
            return "新的密码已经发送到邮箱,注意查收" + randomPwd;
        }
        return "密码修改失败";
    }
}
